from google.appengine.ext import db
from time import gmtime, strftime
from exceptions import *
from invoiceSettings import Tax
import datetime, time

class InvoiceRow(db.Model):
	
	description = db.StringProperty("")
	amount = db.FloatProperty(0)

	def myserialize(self):
		return {
				'key':str(self.key()),
				'description':self.description,
				'amount':self.amount
			}


class InvoiceData(db.Model):

	user = db.UserProperty()
	amount = db.FloatProperty(0)
	unatantum = db.IntegerProperty(default=1)

	invoiceNumber = db.IntegerProperty(default=1)
	
	last_operation = db.DateTimeProperty(auto_now=True)
	created_date = db.DateTimeProperty(auto_now_add=True)
	sent_date = db.DateTimeProperty()
	paid_date = db.DateTimeProperty()
	deleted = db.BooleanProperty(default=False)

	additionals = db.ListProperty(db.Key)
	rows = db.ListProperty(db.Key)
	
	#project = db.ReferenceProperty(reference_class=ProjectData)
	project = db.StringProperty("")
	
	@staticmethod
	def getInvoiceData(user, **trash):
		return map(lambda x: x.myserialize(), InvoiceData.all().filter('user', user).filter("deleted =", False).order('last_operation'))

	@staticmethod
	def getRawSingleInvoiceData(user, key):
		elem = db.get(key)
		return elem.user==user and elem or None

	@staticmethod
	def getSingleInvoiceData(user, key):
		elem = db.get(key)
		return elem.user==user and elem.myserialize() or None
	
	@staticmethod
	def deleteInvoiceData(user, key=None, **trash):
		print key, trash
		if key:
			#pr = db.get(key)
			#if pr.fatturaemessa:
			#	raise FatturaExistException("Non puoi eliminare un progetto per il quale hai gi&agrave; emesso fattura!")
			#pr.delete()
			model = db.get(key)
			model.deleted = True
			model.put()
		else:
			raise MyException("Inexistent key")
	
	def myserialize(self):

		taxes_lst = []
		rows_lst = []

		for key in self.additionals:
			tax = db.get(key)
			taxes_lst.append(tax.myserialize())

		for key in self.rows:
			row = db.get(key)
			rows_lst.append(row.myserialize())

		return {
				'key':str(self.key()),
				#'name':str(self.name),
				#'customer': self.customer and str(self.customer.key()) or None,
				#'closed': self.closed,
				#'unatantum': self.unatantum,
				'amount': self.amount,
				'invoiceNumber': self.invoiceNumber,
				'project': self.project,
				'last_operation':self.last_operation.isoformat(),
				'created_date':self.created_date.isoformat(),
				'additionals': taxes_lst,
				'rows': rows_lst
				#'progress_work':self.progress_work
			}
	
	@staticmethod
	def newInvoice(user, key=None, project=None, amount=None, unatantum=1, additionals=None, rows=None, invoiceNumber=1, **trash):
		invoicedatadb, new = key and (db.get(key), False) or (InvoiceData(), True)
		invoicedatadb.user = user
		if amount:
			try:
				invoicedatadb.amount = float(amount)
			except:
				raise WrongAmountFormatException()
		if invoiceNumber: #TODO
			invoicedatadb.invoiceNumber = invoiceNumber
		if unatantum:
			invoicedatadb.unatantum = unatantum
		if project:
			invoicedatadb.project = project#db.get(project)
		
		if additionals!=None:
			invoicedatadb.additionals = []
			for tax in additionals:
				taxdb = db.get(tax['key'])
				invoicedatadb.additionals.append(taxdb.key())

		if rows!=None:
			invoicedatadb.rows = []
			for row in rows:
				rowdb = InvoiceRow()
				rowdb.description = row['description']

				try:
					rowdb.amount = float(row['amount'])
				except Exception as ex:
					raise WrongAmountFormatException()

				if rowdb.description:
					rowdb.put()
					invoicedatadb.rows.append(rowdb.key())
		
		invoicedatadb.put()
		#warning = (amount and projectdatadb.fatturaemessa and "Modifiche salvate con successo. Hai gi&agrave; creato una fattura per questo progetto, questa non &egrave; stata eliminata ma ti consigliamo comunque di crearne una aggiornata") or None
		#return projectdatadb.myserialize(),new,warning
		return [invoicedatadb.myserialize()]
